package com.yunyao.web.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.yunyao.common.dto.audit.AuditAttachmentDto;
import com.yunyao.common.dto.excel.ContractExcelDto;
import com.yunyao.common.dto.excel.ProjectOrderExcelDto;
import com.yunyao.common.dto.order.ProjectOrderDto;
import com.yunyao.common.dto.project.OrderAuditAttachmentDto;
import com.yunyao.common.dto.supplier.ContractDto;
import com.yunyao.common.web.enums.ResultMsgEnum;
import com.yunyao.common.web.util.PageResult;
import com.yunyao.common.web.util.StringUtils;
import com.yunyao.common.web.util.YResult;
import com.yunyao.framework.dto.audit.ApprovalDto;
import com.yunyao.framework.dto.audit.SubmitApprovalDto;
import com.yunyao.framework.dto.file.FileInfoDto;
import com.yunyao.framework.dto.projectorder.ProjectConsigneeSaveDto;
import com.yunyao.framework.dto.projectorder.ProjectMaterialSaveDto;
import com.yunyao.framework.dto.projectorder.ProjectOrderSaveDto;
import com.yunyao.framework.service.ProjectConsigneeService;
import com.yunyao.framework.service.ProjectMaterialService;
import com.yunyao.framework.service.ProjectOrderService;
import com.yunyao.framework.vo.contract.ContractMaterialVO;
import com.yunyao.framework.vo.projectorder.CheckSupplyVO;
import com.yunyao.framework.vo.projectorder.OrderAuditAttachmentVO;
import com.yunyao.framework.vo.projectorder.OrderSnAndNameVO;
import com.yunyao.framework.vo.projectorder.ProjectConsigneeVO;
import com.yunyao.framework.vo.projectorder.ProjectMaterialVO;
import com.yunyao.framework.vo.projectorder.ProjectOrderVO;
import com.yunyao.web.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 项目订单管理
 *
 * @author chenyejian
 * @date 2024-07-16
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/projectOrder")
public class ProjectOrderController {

    @Autowired
    private ProjectOrderService projectOrderService;
    @Autowired
    private ProjectMaterialService projectMaterialService;
    @Autowired
    private ProjectConsigneeService projectConsigneeService;
    /**
     * 根据条件查询项目订单列表。
     * <p>
     * 通过GET请求访问此方法，可以获取项目订单的分页列表。请求参数包含在ProjectOrderDto对象中，
     * 提供了灵活的查询选项。此方法封装了与服务层的交互，将查询逻辑委托给项目订单服务。
     *
     * @param projectOrderDto 查询条件对象，包含对项目订单的过滤条件和分页信息。
     * @return 返回一个包含项目订单分页结果的YResult对象。YResult对象封装了操作结果的状态和数据，
     * 其中数据部分是一个PageResult对象，包含了当前页的项目订单列表。
     */
    @GetMapping("/list")
    public YResult<PageResult<ProjectOrderVO>> list(ProjectOrderDto projectOrderDto) {
        if (!StringUtils.isEmpty(projectOrderDto.getBeginDate())) {
            projectOrderDto.setBeginDate(projectOrderDto.getBeginDate() + " 00:00:00");
        }
        if (!StringUtils.isEmpty(projectOrderDto.getEndDate())) {
            projectOrderDto.setEndDate(projectOrderDto.getEndDate() + " 23:59:59");
        }
        return projectOrderService.pageList(projectOrderDto);
    }

    /**
     * 根据订单id查询详情
     */
    @GetMapping("/info")
    public YResult<ProjectOrderVO> detail(@NotEmpty(message = "id不能为空") String id) {
        return projectOrderService.getOrderDetailById(id);
    }


    /**
     * 根据订单id查询材料列表
     */
    @GetMapping("/material/list")
    public YResult<PageResult<ProjectMaterialVO>> materialList(ProjectOrderDto projectOrderDto) {
        return projectMaterialService.pageList(projectOrderDto.getId(),
                projectOrderDto.getPageIndex(), projectOrderDto.getPageSize());
    }
    /**
     * 获取合同材料列表
     *
     * @param contractDto
     * @return
     */
    @GetMapping("/material/selectlist")
    public YResult<PageResult<ContractMaterialVO>> getContractMaterialList(ContractDto contractDto) {
        return projectMaterialService.getContractMaterialList(contractDto);
    }

    /**
     * 根据订单id查询收货人
     */
    @GetMapping("/consignee/list")
    public YResult<PageResult<ProjectConsigneeVO>> consigneeList(ProjectOrderDto projectOrderDto) {
        return projectConsigneeService.pageList(projectOrderDto.getId(),
                projectOrderDto.getPageIndex(), projectOrderDto.getPageSize());
    }

    /**
     * 保存项目订单
     */
    @PostMapping("/saveOrUpdate")
    public YResult<String> saveOrUpdate(@RequestBody @Validated ProjectOrderSaveDto projectOrderSaveDto) {
        /**
         * 判断是否超出合同总价和数量,如果超出则提示用户
         */
        /**
         * todo try {
         *             YResult<String> result = projectOrderService.checkTotalPriceAndMaterialSum
         *             (projectOrderSaveDto);
         *             if(!ResultMsgEnum.SUCCESS.getCode().equals(result.getCode())){
         *                 return result;
         *             }}catch (Exception e){
         *             log.error("判断合同金额和数量异常",e);
         *         }
         **/
        if (CollectionUtils.isEmpty(projectOrderSaveDto.getMaterialList())){
            return YResult.error("请添加材料");
        }
        return projectOrderService.saveOrUpdate(projectOrderSaveDto);
    }

    /**
     * 保存订单材料信息
     */
    @PostMapping("/material/saveOrUpdate")
    public YResult<String> materialSaveOrUpdate(@RequestBody ProjectMaterialSaveDto saveDto) {
        return projectMaterialService.saveOrUpdate(saveDto);
    }


    /**
     * 保存订单收货人
     */
    @PostMapping("/consignee/saveOrUpdate")
    public YResult<String> consigneeSaveOrUpdate(@RequestBody ProjectConsigneeSaveDto saveDto) {
        return projectConsigneeService.saveOrUpdate(saveDto);
    }

    /**
     * 删除项目订单
     */
    @PostMapping("/deleteByIds")
    public YResult<String> deleteByIds(String[] ids) {
        return projectOrderService.deleteByIds(ids);
    }

    /**
     * 删除订单材料信息
     */
    @PostMapping("/material/deleteByIds")
    public YResult<String> materialDeleteByIds(String[] ids) {
        return projectMaterialService.deleteByIds(ids);
    }


    /**
     * 删除订单收货人
     */
    @PostMapping("/consignee/deleteByIds")
    public YResult<String> consigneeDeleteByIds(@RequestBody String[] ids) {
        return projectConsigneeService.deleteByIds(ids);
    }

    /**
     * 删除项目订单
     */
    @PostMapping("/deleteById")
    public YResult<String> deleteById(@RequestBody ProjectOrderDto dto) {
        if (StringUtils.isEmpty(dto.getId())) {
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return projectOrderService.deleteByIds(ids);
    }

    /**
     * 删除订单材料信息
     */
    @PostMapping("/material/deleteById")
    public YResult<String> materialDeleteById(@RequestBody ProjectMaterialSaveDto dto) {
        if (StringUtils.isEmpty(dto.getId())) {
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return projectMaterialService.deleteByIds(ids);
    }

    /**
     * 删除订单收货人
     */
    @PostMapping("/consignee/deleteById")
    public YResult<String> consigneeDeleteByIds(@RequestBody ProjectConsigneeSaveDto dto) {
        if (StringUtils.isEmpty(dto.getId())) {
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        String[] ids = new String[1];
        ids[0] = dto.getId();
        return projectConsigneeService.deleteByIds(ids);
    }

    /**
     * 提交审批项目订单
     */
    @PostMapping("/submit/approval")
    public YResult<String> submitApproval(@RequestBody @Validated SubmitApprovalDto submitApprovalDto) {
        return projectOrderService.submitApproval(submitApprovalDto);
    }


    /**
     * 审批
     *
     * @return
     */
    @PostMapping("/approval")
    public YResult<String> approval(@RequestBody @Validated ApprovalDto approvalDto) {
        return projectOrderService.approval(approvalDto);
    }


    /**
     * 项目订单供货完成
     */
    @PostMapping("/supplyFinish")
    public YResult<String> supplyFinish(@RequestBody ProjectOrderDto dto) {
        if (StringUtils.isEmpty(dto.getId())) {
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        return projectOrderService.supplyFinish(dto.getId());
    }

    /**
     * 撤销
     *
     * @return
     */
    @PostMapping("/revocation")
    public YResult<String> revocation(@RequestBody @Validated ApprovalDto approvalDto) {
        return projectOrderService.revocation(approvalDto);
    }


    /**
     * 项目订单，订单确认（供应商）
     */
    @PostMapping("/commitAudit")
    public YResult<String> auditOrder(@RequestBody ProjectOrderDto dto) {
        return projectOrderService.audit(dto);
    }



    /**
     * 根据合同id生成项目订单编号和项目名称
     */
    @GetMapping("/getSnAndName")
    public YResult<OrderSnAndNameVO> getSnAndName(ProjectOrderDto projectOrderDto) {
        if (StringUtils.isEmpty(projectOrderDto.getContractId())){
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        return projectOrderService.getSnAndNameByContractId(projectOrderDto.getContractId());
    }


    /**
     * 查看审批附件信息
     */
    @GetMapping("/audit/attachment/info")
    public YResult<OrderAuditAttachmentVO> getAttachmentInfo(AuditAttachmentDto attachmentDto) {
        if (StringUtils.isEmpty(attachmentDto.getBizId())){
            return YResult.error(ResultMsgEnum.PARAM_ERROR);
        }
        return projectOrderService.getAttachmentInfo(attachmentDto.getBizId());
    }


    /**
     * 保存审批附件
     */
    @PostMapping("/audit/attachment/save")
    public YResult<String> saveAttachment(@RequestBody OrderAuditAttachmentDto attachmentDto) {
        return projectOrderService.saveAuditCloudAttachment(attachmentDto);
    }


    /**
     * 判断是否完全供货
     */
    @GetMapping("/check/supplyStatus")
    public YResult<CheckSupplyVO> checkSupplyStatus(ProjectOrderDto projectOrderDto) {
        if (projectOrderDto == null || (StringUtils.isEmpty(projectOrderDto.getId()) && StringUtils.isEmpty(projectOrderDto.getProjectId()))) {
            return YResult.error("参数错误");
        }
        if (StringUtils.isEmpty(projectOrderDto.getId())){
            projectOrderDto.setId(projectOrderDto.getProjectId());
        }
        return projectOrderService.checkSupplyStatus(projectOrderDto);
    }


    /**
     * 根据订单id查询材料列表总和
     */
    @GetMapping("/material/list/count")
    public YResult<ProjectMaterialVO> materialListCount(ProjectOrderDto projectOrderDto) {
        return projectMaterialService.materialListCount(projectOrderDto.getId());
    }


    /**
     * 导出文件
     *
     * @return
     */

    @GetMapping("/export/file")
    public YResult<String> exportFile(ProjectOrderDto projectOrderDto, HttpServletResponse response) {
        try {
            if (!StringUtils.isEmpty(projectOrderDto.getBeginDate())) {
                projectOrderDto.setBeginDate(projectOrderDto.getBeginDate() + " 00:00:00");
            }
            if (!StringUtils.isEmpty(projectOrderDto.getEndDate())) {
                projectOrderDto.setEndDate(projectOrderDto.getEndDate() + " 23:59:59");
            }
            List<ProjectOrderExcelDto> contractMaterialExportDtoList =  projectOrderService.export(projectOrderDto);
            try {
                // 这里URLEncoder.encode可以防止中文乱码
                String fileName = URLEncoder.encode("projectOrder", String.valueOf(StandardCharsets.UTF_8))+".xlsx";
//                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                //设置sheet名
                ExportParams params = new ExportParams();
                params.setSheetName("订单信息模版");
                //设置标题
//                params.setTitle("商品信息");
                // 这里需要设置不关闭流
                Workbook workbook = ExcelExportUtil.exportExcel(params, ProjectOrderExcelDto.class, contractMaterialExportDtoList);
                //输出流
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] bytes = bos.toByteArray();
                bos.close();
                try {
                    FileInfoDto fileInfoDto = AliOssUtil.upload(bytes,
                            fileName, null);
                    if (null != fileInfoDto) {
                        return YResult.success(fileInfoDto.getLink());
                    } else {
                        return YResult.error("连接文件服务器失败，请重试");
                    }
                } catch (Exception e) {
                    return YResult.error("下载失败，请重试");
                }
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }catch (Exception e) {
            log.error("导出订单信息失败",e);
        }
        return YResult.error("导出订单信息失败");
    }
}
